import uicls
import uiutil
import uiconst
import blue
import math
import uitest
import log

class Transform(uitest.BaseDecoCore, uicls._GetDecoMetaclassInst('trinity.Tr2Sprite2dTransform')):
    __guid__ = 'uicls.NewTransform'
    default_name = 'transform'
    default_state = uiconst.UI_PICKCHILDREN
    default_rotation = 0.0
    displayWidth = 0.0
    displayHeight = 0.0

    def ApplyAttributes(self, attributes):
        uitest.BaseDecoCore.ApplyAttributes(self, attributes)
        self.SetRotation(attributes.get('rotation', self.default_rotation))



    def SetRotation(self, rotation = 0):
        self.rotation = -rotation



    def GetRotation(self):
        return self.rotation



    def StartRotationCycle(self, direction = 1, cycleTime = 1000.0):
        if getattr(self, '_rotateCycle', False):
            self._rotateCycle = False
            blue.pyos.synchro.Yield()
        self._rotateCycle = True
        fullRotation = (math.pi * 2)
        start = blue.os.GetTime()
        ndt = 0.0
        current = self.GetRotation()
        while getattr(self, '_rotateCycle', False):
            try:
                ndt = max(ndt, (blue.os.TimeDiffInMs(start) / cycleTime))
            except:
                log.LogWarn(('StartRotationCycle::Failed getting time diff. Diff should not exceed %s but is %s' % (cycleTime, (start - blue.os.GetTime(1)))))
                ndt = 1.0
            self.SetRotation((current - ((fullRotation * ndt) * direction)))
            blue.pyos.synchro.Yield()
            if self.destroyed:
                return 




    def Rotate(self, delta):
        newRotation = self.ClampRotation((self.rotation + delta))
        self.SetRotation(newRotation)



    def ClampRotation(self, rotation):
        if (rotation > (math.pi * 2)):
            rotation -= (math.pi * 2)
        elif (rotation < 0):
            rotation += (math.pi * 2)
        return rotation



    def StopRotationCycle(self):
        self._rotateCycle = False



    def GetAlignmentBudgetForChild(self, child):
        (l, t, w, h,) = self.GetAbsolute()
        l = t = 0
        for mychild in self.children:
            if (mychild == child):
                break
            if ((mychild.display == False) or (not hasattr(mychild, 'GetAlign'))):
                continue
            mcAlign = mychild.GetAlign()
            if (mcAlign not in self.__push_alignments__):
                continue
            (padLeft, padTop, padRight, padBottom,) = mychild.GetPadding()
            if (mcAlign == uiconst.TOLEFT):
                l += ((mychild.displayWidth + padLeft) + padRight)
                w -= ((mychild.displayWidth + padLeft) + padRight)
            elif (mcAlign == uiconst.TORIGHT):
                w -= ((mychild.displayWidth + padLeft) + padRight)
            elif (mcAlign == uiconst.TOTOP):
                t += ((mychild.displayHeight + padTop) + padBottom)
                h -= ((mychild.displayHeight + padTop) + padBottom)
            else:
                if (mcAlign == uiconst.TOBOTTOM):
                    h -= ((mychild.displayHeight + padTop) + padBottom)

        return (l,
         t,
         w,
         h)



    def OnSetAttr(self, k, v):
        uitest.BaseDecoCore.OnSetAttr(self, k, v)



    def GetAbsolute(self):
        (l, t,) = self.GetAbsolutePosition()
        return (l,
         t,
         self.displayWidth,
         self.displayHeight)



    def AddChild(self, child, idx = -1):
        if (idx == -1):
            idx = len(self.children)
        self.children.insert(idx, child)



    def RemoveChild(self, child):
        if self.destroyed:
            return 
        doUpdate = False
        if (child in self.children):
            idx = self.children.index(child)
            if (child.GetAlign() in self.__push_alignments__):
                doUpdate = True
            self.children.remove(child)



    def Flush(self):
        for child in self.children[:]:
            if hasattr(child, 'Close'):
                if not getattr(child, 'destroyed', 0):
                    child.Close()
            else:
                self.children.remove(child)




    def SetOpacity(self, opacity):
        return 



    def UpdateAlignment(self, budget = None, *args, **kw):
        ret = uitest.BaseDecoCore.UpdateAlignment(self, budget)
        self.rotationCenter = ((self.displayWidth / 2), (self.displayHeight / 2))
        return ret




